home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 330_03 / tskprf.asm < prev    next >
Assembly Source File  |  1990-10-10  |  30KB  |  1,659 lines

  1. ;
  2. ;    --- Version 2.2 90-10-12 10:38 ---
  3. ;
  4. ;    CTask - Printf replacement
  5. ;
  6. ;    Public Domain Software written by
  7. ;        Thomas Wagner
  8. ;        Ferrari electronic Gmbh
  9. ;        Beusselstrasse 27
  10. ;        D-1000 Berlin 21
  11. ;        Germany
  12. ;
  13. ;    This file is new with Version 2.1. 
  14. ;
  15. ;    This module contains substitutes for the standard C printf
  16. ;    family formatting routines. It uses no helper routines, and
  17. ;    thus can be called from Assembler programs and is model
  18. ;    independent. It is smaller and faster (up to 5 times) than
  19. ;    the standard C printf, and supports all output options except 
  20. ;    floating point and some esoteric flags. 
  21. ;
  22. ;    Also supported is output to the second monitor in a dual-
  23. ;    monitor system.
  24. ;
  25. ;    The routines in this module are reentrant in the sense that nothing
  26. ;    will crash if routines are re-entered concurrently. No protection
  27. ;    against a garbled screen is built in, however, so external
  28. ;    resource request/release calls are still necessary to make
  29. ;    sure output to the display stays in proper order. The sprintf
  30. ;    routines need no protection.
  31. ;
  32. ;    No CTask specific stuff is used to allow use of the routines
  33. ;    even when CTask is not installed.
  34. ;
  35. ;    Note that the tsk_fprintf routine takes a different parameter
  36. ;    than the standard fprintf. You have to pass an integer file 
  37. ;    handle, not a FILE *.
  38. ;
  39. ;---------------------------------------------------------------------------
  40. ;
  41. ;    Conversion format:
  42. ;
  43. ;        % [flags] [width] [.precision] [indirection] [size] conversion
  44. ;
  45. ;    Flags supported:
  46. ;
  47. ;        -    Left-justify output
  48. ;
  49. ;        the +, blank, and # flags are not supported.
  50. ;
  51. ;    Width and precision are handled like in standard C, i.e.
  52. ;    the * specification is supported. The only exception is
  53. ;    that numeric output will not be suppressed for an explicit
  54. ;    0 precision.
  55. ;
  56. ;    Size modifiers supported:
  57. ;
  58. ;        N    Near pointer
  59. ;        F    Far pointer
  60. ;        h    Short
  61. ;        l    Long
  62. ;
  63. ;    Conversion characters supported:
  64. ;
  65. ;        c    single character
  66. ;        s    zero-terminated string
  67. ;        x    unsigned hex word, a-f
  68. ;        X    unsigned hex word, A-F
  69. ;        d    signed decimal int
  70. ;        u    unsigned decimal int
  71. ;        p    hex pointer, a-f
  72. ;        P    hex pointer, A-F
  73. ;        n    store converted length at int pointer
  74. ;
  75. ;    In addition, two indirection operators are supported. Both
  76. ;    can be repeated, but they should not normally be mixed.
  77. ;
  78. ;        ^    Near indirection (param is DS-based near pointer)
  79. ;        @    Far indirection (param is far pointer)
  80. ;
  81. ;    Example:
  82. ;        %d    Displays the word parameter
  83. ;        %^d    Displays the word at DS:parameter
  84. ;        %@d    Displays the word at the far address 
  85. ;            given as parameter
  86. ;
  87. ;---------------------------------------------------------------------------
  88. ;
  89.     name    tskprf
  90. ;
  91.     include    tsk.mac
  92. ;
  93.     .tsk_model
  94. ;
  95.     public    tsk_regen        ; far pointer to regen buffer
  96.     public    tsk_regen_s        ; regen buffer segment
  97.     public    tsk_regen_o        ; current regen buffer offset
  98.     public    tsk_disport        ; display controller I/O port
  99. ;
  100.     Pubfunc    tsk_putc        ; put char to screen
  101.     Pubfunc    tsk_puts        ; put string to screen
  102.     Pubfunc    tsk_rputc        ; put char to regen
  103.     Pubfunc    tsk_rputs        ; put string to regen
  104. ;
  105.     CPubfnc    tsk_printf        ; print to screen
  106.     Pubfunc    tsk_vprintf        ; print to screen with arg pointer
  107.     CPubfnc    tsk_fprintf        ; print to file handle
  108.     Pubfunc    tsk_vfprintf        ; print to file handle w. argptr
  109.     CPubfnc    tsk_sprintf        ; print to string
  110.     Pubfunc    tsk_vsprintf        ; print to string w. argptr
  111.     CPubfnc    tsk_rprintf        ; print to regen
  112.     Pubfunc    tsk_vrprintf        ; print to regen w. argptr
  113. ;
  114.     Pubfunc    tsk_setpos        ; set regen cursor position
  115.     Pubfunc    tsk_set_regen        ; set regen address
  116.     Pubfunc    tsk_set_dualdis        ; init secondary monitor
  117.     Pubfunc    tsk_set_currdis        ; init primary monitor
  118.     Pubfunc    tsk_set_colour        ; init colour monitor
  119.     Pubfunc    tsk_set_mono        ; init mono monitor
  120.     Pubfunc    tsk_set_attr        ; set display attribute
  121.     Pubfunc    tsk_set_clreol        ; CR clears to EOL when set
  122. ;
  123. ;
  124. ; Configuration options:
  125. ;
  126. ; FILE_BUFSIZE    Is the local buffer size for tsk_fprintf and tsk_vfprintf.
  127. ;        The buffer is allocated on the stack, so it should
  128. ;        not be chosen too large to avoid stack overflows.
  129. ;        It must be a power of 2, and less than or equal to 256.
  130. ;
  131. FILE_BUFSIZE    =    64 - 1
  132. ;
  133. ;
  134. ; DFLT_FAR    If set, pointers (%p and %n) and strings (%s) are assumed
  135. ;        far by default, near pointers must use the N size
  136. ;        modifiers.
  137. ;        If clear, the default is near, so the F size modifier
  138. ;        must be used for far pointers.
  139. ;
  140. DFLT_FAR    =    1    ; by default, pointers and strings are Far
  141. ;
  142. ;
  143. ;    The local variables used in the main formatter.
  144. ;    Those variables are relative to BP, and are accessed by
  145. ;    several routines in this module (the local routines do not
  146. ;    use the standard stack discipline, they should be viewed as
  147. ;    Pascal-like nested routines within the scope of @disprintf).
  148. ;
  149. dislocrec    struc
  150. convbuf    db    11 dup(?)    ; conversion buffer (hex/dec)
  151. prflags    db    ?        ; formatting flags
  152. prhexch    db    ?        ; Hex format offset for upper/lower case
  153. prfcnt    db    ?        ; file output counter
  154. procnt    dw    ?        ; output char counter
  155. prwidth    dw    ?        ; field width
  156. prec    dw    ?        ; precision
  157. arglen    dw    ?        ; argument length in bytes
  158. prproc    dw    ?        ; output routine offset
  159. prargbx    dw    ?        ; output routine BX argument
  160. prargdx    dw    ?        ; output routine DX argument
  161. dislocrec    ends
  162. ;
  163. ;    formatting flags
  164. ;
  165. F_LONGARG    =    01h    ; argument is long/far (4 bytes)
  166. F_SHORTARG    =    02h    ; argument is single byte
  167. F_PADZERO    =    04h    ; pad with zeros
  168. F_LEFTADJ    =    08h    ; left adjust output
  169. F_SIGNED    =    10h    ; signed number
  170. F_WIDTH        =    20h    ; width is valid
  171. F_PREC        =    40h    ; precision is valid
  172. F_INDIR        =    80h    ; indirection was used
  173. ;
  174. biosdata    segment at 40h
  175.         org    4ah
  176. bios_cols    dw    ?
  177.         org    63h
  178. bios_chipad    dw    ?
  179.         org    84h
  180. bios_rows    db    ?
  181. biosdata    ends
  182. ;
  183.     .tsk_data
  184. ;
  185. tsk_regen    label    dword
  186. tsk_regen_o    dw    0
  187. tsk_regen_s    dw    0b000h        ; default mono screen
  188. ;
  189. tsk_disport    dw    3b4h        ; default mono 6845
  190. tsk_attrib    db    07h        ; default white on black
  191. ;
  192. sc_clreol    db    0        ; default is don't clear
  193. ;
  194. sc_cols    dw    80 * 2
  195. sc_end    dw    25 * 80 * 2
  196. ;
  197. sc_proc    dw    offset @nodis
  198. ;
  199.     .tsk_edata
  200.     .tsk_code
  201. ;
  202. ctdataseg    dw    @CTASK_DATA
  203. ;
  204. ;    setcsr - local routine to set the cursor to the current position
  205. ;         on the regen display.
  206. ;
  207. @setcsr    proc    near
  208. ;
  209.     push    dx
  210.     mov    dx,tsk_disport
  211.     or    dx,dx
  212.     jz    no_cursor
  213.     mov    al,0eh
  214.     out    dx,al
  215.     jmp    $+2
  216.     mov    ax,tsk_regen_o
  217.     shr    ax,1
  218.     xchg    ah,al
  219.     inc    dx
  220.     out    dx,al
  221.     jmp    $+2
  222.     dec    dx
  223.     mov    al,0fh
  224.     out    dx,al
  225.     jmp    $+2
  226.     mov    al,ah
  227.     inc    dx
  228.     out    dx,al
  229. ;
  230. no_cursor:
  231.     pop    dx
  232.     ret
  233. ;
  234. @setcsr    endp
  235. ;
  236. ;
  237. ; disregen - local routine to write char directly into the display 
  238. ;    regen buffer. The following control characters 
  239. ;    are handled special:
  240. ;        08 \b (BS)      backspace one position (no erase)
  241. ;        09 \t (TAB)    tab to next 8th column
  242. ;        0D \r (CR)    carriage return
  243. ;        0A \n (LF)    line feed
  244. ;                Note: the printf routines will not pass
  245. ;                a single line feed unchanged.
  246. ;        0B \v (VT)    clear to end of line
  247. ;        0C \f (FF)    clear to end of screen
  248. ;
  249. ;
  250. ;    Entry:    AL = char to display
  251. ;    Uses:    AX
  252. ;
  253. @disregen    proc    near
  254. ;
  255.     push    ds
  256.     mov    ds,cs:ctdataseg        ; allow access to local vars
  257. ;
  258. ;    First, check for control characters
  259. ;
  260.     cmp    al,0eh            ; 08-0D are special
  261.     jae    no_special
  262.     cmp    al,08h
  263.     jb    no_special
  264.     je    dis_bs            ; 08 = Backspace
  265.     cmp    al,0ah
  266.     jb    dis_tab            ; 09 = Tab
  267.     je    dis_lf            ; 0A = Linefeed
  268.     cmp    al,0ch
  269.     jb    dis_vt            ; 0B = Clear to eol
  270.     jne    dis_cr            ; 0D = Carriage return
  271.     jmp    dis_ff            ; 0C = Clear screen
  272. ;
  273. ;    Carriage return
  274. ;
  275. dis_cr:
  276.     cmp    sc_clreol,0
  277.     jne    dis_vt
  278. discr1:
  279.     push    dx
  280.     cli
  281.     mov    ax,tsk_regen_o        ; current offset
  282.     xor    dx,dx            ; make into doubleword
  283.     div    sc_cols            ; divide by number of columns
  284.     sub    tsk_regen_o,dx        ; subtract remainder
  285.     sti
  286.     pop    dx
  287.     jmp    disreg_end
  288. ;
  289. no_special:
  290.     jmp    disregen_ok
  291. ;
  292. ;    Backspace
  293. ;
  294. dis_bs:
  295.     cli
  296.     cmp    tsk_regen_o,0        ; Handle wraparound
  297.     je    dis_bs2
  298.     sub    tsk_regen_o,2
  299.     sti
  300.     jmp    disreg_end
  301. dis_bs2:
  302.     mov    ax,sc_end        ; Wrap to end of screen
  303.     sub    ax,2
  304.     mov    tsk_regen_o,ax
  305.     sti
  306.     jmp    disreg_end
  307. ;
  308. ;    Tab
  309. ;
  310. dis_tab:
  311.     cli
  312.     mov    ax,tsk_regen_o
  313.     add    ax,16
  314.     and    ax,0fff0h        ; Tabs every 8 cols
  315.     mov    tsk_regen_o,ax
  316.     sti
  317.     jmp    disreg_end
  318. ;
  319. ;    Linefeed
  320. ;
  321. dis_lf:
  322.     cli
  323.     mov    ax,tsk_regen_o
  324.     add    a